import { Injector, Output, EventEmitter } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { map } from 'rxjs/operators';
import { ListResult } from './api-base';
import { MatDialog } from '@angular/material';
import { SweetAlertService } from '../share/services/sweet-alert.service';
import { ToasterService } from '../share/services/toaster.service';

export class ListBase {
	constructor(
		private _inject: Injector,
		public dialog = _inject.get(MatDialog),
		protected router = _inject.get(Router),
		protected route = _inject.get(ActivatedRoute),
		protected sweet = _inject.get(SweetAlertService),
		protected toaster = _inject.get(ToasterService),
	) {}

	@Output() selectedChange = new EventEmitter<Array<number>>();

	sort = {};
	selectedAll = false;
	selected = new Set();

	getData<T = any>(key: string) {
		return this.route.data.pipe(map(data => data[key] as T));
	}

	getList<T>() {
		return this.getData<ListResult<T>>('list');
	}

	reload() {
		this.router.navigated = false;
		this.router.navigate([], { queryParamsHandling: 'merge' });
	}

	goDetail(id: number, name: string) {
		this.router.navigate(['detail', name], { relativeTo: this.route, queryParams: { id: id.toString() } });
	}

	//  sort object
	sortChange(name: string, order: string, merge = false) {
		if (merge) {
			this.sort = { ...this.sort, [name]: order };
		} else {
			this.sort = { [name]: order };
		}
	}

	// select change
	selectChange(id: any) {
		this.selected.has(id) ? this.selected.delete(id) : this.selected.add(id);
		this.selected = new Set(this.selected);
		this.selectedChange.emit(this.selectedArray());
	}
	// select all
	selectAll<T extends { id: any }>(arr: Array<T>, primaryKey: keyof T = 'id') {
		this.selectedAll = !this.selectedAll;
		if (this.selectedAll) {
			arr.forEach(obj => this.selected.add(obj[primaryKey]));
		} else {
			arr.forEach(obj => this.selected.delete(obj[primaryKey]));
		}
		this.selected = new Set(this.selected);
		this.selectedChange.emit(this.selectedArray());
	}
	// check select all
	selectAllCheck<T extends { id: any }>(arr: T[], primaryKey: keyof T = 'id') {
		this.selectedAll = arr.every(obj => this.selected.has(obj[primaryKey]));
	}
	// selected to array
	selectedArray() {
		return Array.from(this.selected);
	}
}
